/**
 * 
 */
package com.letv.ads.view;

import static com.letv.adlib.sdk.types.AdElement.AdClickShowType.SHOW_EXTERNALWEBBROWSER;
import static com.letv.adlib.sdk.types.AdElement.AdClickShowType.SHOW_INSTALLAPK;
import static com.letv.adlib.sdk.types.AdElement.AdClickShowType.SHOW_INTERNALWEBVIEW;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Typeface;
import android.media.AudioManager;
import android.os.Bundle;
import android.os.Handler;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.letv.adlib.managers.status.ad.AdStatusManager;
import com.letv.adlib.sdk.types.AdElement.AdClickShowType;
import com.letv.adlib.sdk.types.AdElement.AdMediaType;
import com.letv.adlib.sdk.types.AdElementMime;
import com.letv.ads.AdsManager;
import com.letv.android.sdk.R;
import com.letv.ads.util.AdsUtils;
import com.letv.ads.util.LogInfo;
import com.letv.ads.view.AdWebView.AdWebviewEventListener;
import com.letv.ads.view.IAdView.AdMaterialLoadListener;
import com.letv.ads.view.IAdView.AdPlayStateListener;
import com.letv.ads.view.IAdView.AdViewOnclickListenr;

/**
 * Created by chengjian 下午5:20:51 代理广告自定义view，减少调用者对广告自定义view的依赖
 *
 */
public class AdView extends RelativeLayout implements IAdView,
        AdViewOnclickListenr, AdPlayStateListener, AdMaterialLoadListener,
        View.OnClickListener {
    private static final String TAG = "AdView";

    private static final int BEGIN_AD = 1;
    private static final int MSG_COUNT_DOWN = 1;
    private static final int MSG_LOADING_TIMEOUT = 2;
    private static final int FREQUENCY_COUNT_DOWN = 500;
    private static final int LOADING_TIMEOUT_DURATION = 3000;
    /**
     * 倒计时总数,默认为3s
     */
    private int mCountDownDur = 3;
    private ClientListener mClientListener;
    private AttributeSet mAttributeSet;
    private IAdView mAdview;
    private Context mContext;
    private int mAdType = 0;
    private boolean mCanClose = false;
    private boolean mShowMute = false;
    private TextView mTimeTextView;
    private ImageView mMuteView;
    private AdElementMime mAdInfo;
    private AdPlayStateListener mAdPlayStateListener;
    private AdMaterialLoadListener mAdMaterialLoadListener;
    private AdWebviewEventListener mAdWebviewEventListener;
    private AudioManager mAudioManager;
    private int mOldVolume;
    private long mStartTime;
    private Handler mHandler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            int what = msg.what;
            switch (what) {
            case MSG_COUNT_DOWN: {
                int currentPos;
                if (mAdview instanceof AdVideoView) {
                    currentPos = ((AdVideoView) mAdview).getCurrentPosition() / 1000;
                } else {
                    currentPos = (int) ((System.currentTimeMillis() - mStartTime) / 1000);
                }
                int remaining = mCountDownDur - currentPos;
                LogInfo.log(TAG, "handleMessage count down mAdview=" + mAdview
                        + " currentPos=" + currentPos);
                if (remaining > 0) {
                    mTimeTextView.setText(remaining + "");
                    sendEmptyMessageDelayed(MSG_COUNT_DOWN,
                            FREQUENCY_COUNT_DOWN);
                } else {
                    notifyPlayState(PLAY_STATE_COMPLETE);
                    closeAD();
                }
                break;
            }
            case MSG_LOADING_TIMEOUT: {
                LogInfo.log(TAG, "handleMessage time out");
                notifyPlayState(PLAY_STATE_ERROR);
                closeAD();
                break;
            }
            }
        }
    };

    // private AdElementMime mAdElementMime;

    /**
     * ，点击广告时，有时需要调用客户端功能，比如说点播，直播
     */
    public interface ClientListener {

        boolean handleADClick(AdElementMime adElementMime);
    }

    public AdView(Context context) {
        super(context);
        mContext = context;
    }

    /**
     * @param context
     * @param attrs
     */
    public AdView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
        mAttributeSet = attrs;
        TypedArray ta = context.obtainStyledAttributes(attrs,
                R.styleable.adview);
        mCanClose = ta.getBoolean(R.styleable.adview_canClose, false);
        mShowMute = ta.getBoolean(R.styleable.adview_showMute, false);
        mAdType = ta.getInt(R.styleable.adview_adType, 0);
    }

    private void initView() {
        inflate(mContext, R.layout.letv_ad_view, this);
        mAudioManager = (AudioManager) mContext
                .getSystemService(Context.AUDIO_SERVICE);
        // 开机广告显示倒计时和跳过广告.
        if (BEGIN_AD == mAdType) {
            View view = findViewById(R.id.ad_skip_layout);
            view.setVisibility(View.VISIBLE);
            TextView skipAdView = (TextView) findViewById(R.id.skip_ad);
            skipAdView.setOnClickListener(this);
            mTimeTextView = (TextView) findViewById(R.id.time);
            mTimeTextView.setTypeface(Typeface.createFromAsset(getContext()
                    .getAssets(), "fonts/ads_digital.ttf"));
        }
        if (mCanClose) {
            View view = findViewById(R.id.close_ad);
            view.setVisibility(View.VISIBLE);
            view.setOnClickListener(this);
        }
    }

    public AttributeSet getAttributeSet() {
        return mAttributeSet;
    }

    /**
     * 设置广告点击回调
     */
    public void setClientListener(ClientListener listener) {
        this.mClientListener = listener;
    }

    @Override
    public void showAD(AdElementMime adInfo) {
        removeAllViews();
        initView();
        LogInfo.log(TAG, "showAD adInfo=" + adInfo);
        mAdInfo = adInfo;
        // 目前除前贴外（不走此逻辑）只有开机广告有倒计时
        if (mAdType == BEGIN_AD) {
            if (adInfo.duration > 0) {
                mCountDownDur = adInfo.duration;
            }
            // 不影响开机速度，加载超时时长为3s
            mHandler.sendEmptyMessageDelayed(MSG_LOADING_TIMEOUT,
                    LOADING_TIMEOUT_DURATION);
        }
        LogInfo.log(TAG, "showAD mediaFileType=" + adInfo.mediaFileType);
        switch (adInfo.mediaFileType) {
        case AdMediaType.PLAIN: {
            mAdview = new AdTextView(mContext, mAttributeSet);
            break;
        }
        case AdMediaType.HTML: {
            mAdview = new AdWebView(mContext, mAttributeSet);
            adInfo.clickShowType = AdClickShowType.SHOW_NOACTION;
            if (null != mAdWebviewEventListener) {
                ((AdWebView) mAdview)
                        .setWebEventListener(mAdWebviewEventListener);
            }
            break;
        }
        case AdMediaType.BITMAP: {
            mAdview = new AdImgaeView(mContext, mAttributeSet);
            break;
        }
        case AdMediaType.DYNAMIC: {
            mAdview = new AdGifView(mContext, mAttributeSet);
            break;
        }
        case AdMediaType.VIDEO: {
            mOldVolume = getVideoVolume();
            if (mShowMute) {
                mMuteView = (ImageView) findViewById(R.id.ad_mute);
                mMuteView.setVisibility(View.VISIBLE);
                mMuteView.setOnClickListener(this);
                mMuteView
                        .setImageResource(mOldVolume == 0 ? R.drawable.letv_boot_mute
                                : R.drawable.letv_boot_not_mute);
            }
            mAdview = new AdVideoView(mContext, mAttributeSet);
            break;
        }
        default: {
            LogInfo.log(TAG, "showAD default type=" + adInfo.mediaFileType);
            break;
        }
        }
        if (null != mAdview) {
            mAdview.setAdOnClickListener(this);
            mAdview.setAdPlayStateListener(this);
            mAdview.setAdMaterialLoadListener(this);
            mAdview.showAD(adInfo);
            FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
                    LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
            params.gravity = Gravity.CENTER;
            if (mAdview instanceof View && null == ((View) mAdview).getParent()) {
                LogInfo.log(TAG, "add pause view");
                addView((View) mAdview, 0, params);
            }
        }
    }

    @Override
    public void closeAD() {
        setVisibility(GONE);
        if (null != mAdInfo) {
            if (AdMediaType.VIDEO == mAdInfo.mediaFileType) {
                // 还原音量
                mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC,
                        mOldVolume, 0);
            }
        }
        if (null != mAdview) {
            mAdview.closeAD();
            return;
        }
    }

    /*
     * @see com.letv.ads.view.IAdView#setAdOnClickListener(com.letv.ads.view.
     * AdViewOnclickListenr)
     */
    @Override
    public void setAdOnClickListener(AdViewOnclickListenr adViewOnclickListenr) {
        if (null != mAdview) {
            mAdview.setAdOnClickListener(adViewOnclickListenr);
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.letv.ads.view.IAdView#setAdMaterialDownloadListener(com.letv.ads.
     * view.IAdView.AdMaterialDownloadListener)
     */
    @Override
    public void setAdMaterialLoadListener(
            AdMaterialLoadListener adMaterialDownloadListener) {
        mAdMaterialLoadListener = adMaterialDownloadListener;
    }

    public void setWebEventListener(
            AdWebviewEventListener adWebviewEventListener) {
        mAdWebviewEventListener = adWebviewEventListener;
    }

    /**
     * 判断点击事件是否被处理
     */
    private boolean handleADClick(AdElementMime adElementMime) {
        if (null != adElementMime) {
            switch (adElementMime.clickShowType) {
            case SHOW_INSTALLAPK: {
                AdsManager.getInstance().downloadAndInstallApk(
                        adElementMime.getClickThrough(), adElementMime.text);
                return true;
            }
            case SHOW_EXTERNALWEBBROWSER:
            case SHOW_INTERNALWEBVIEW: {
                clickGotoWeb(adElementMime);
                return true;
            }
            default: {
                return false;
            }
            }
        }
        return false;
    }

    /**
     * 点击广告跳转到系统浏览器,并请求点击曝光地址和第三方点击曝光地址
     */
    private void clickGotoWeb(AdElementMime adElementMime) {
        String clickThrough = adElementMime.getClickThrough();
        LogInfo.log(TAG, "clickGotoWeb() clickThrough=" + clickThrough);
        if (!TextUtils.isEmpty(clickThrough)) {
            AdsUtils.gotoWeb(getContext(), adElementMime);
        }
    }

    @Override
    public void onADClick(AdElementMime adElementMime) {
        if (null != adElementMime) {
            boolean ishandle = handleADClick(adElementMime);
            if (!ishandle && null != mClientListener) {
                // 如果广告sdk没有处理则交给客户端处理.
                ishandle = mClientListener.handleADClick(adElementMime);
            }
            if (ishandle && BEGIN_AD == mAdType) {
                // 开机广告点击如果有响应就结束广告
                notifyPlayState(PLAY_STATE_COMPLETE);
                closeAD();
            }
            /**
             * 点击统计
             * */
            AdStatusManager statusMgr = new AdStatusManager(adElementMime);
            statusMgr.onAdClicked();
        }
    }

    @Override
    public void onClick(View v) {
        int id = v.getId();
        if (R.id.skip_ad == id || R.id.close_ad == id) {
            closeAD();
            notifyPlayState(PLAY_STATE_COMPLETE);
        } else if (R.id.ad_mute == id) {
            int curVolume = getVideoVolume();
            if (curVolume == 0) {
                if (mOldVolume == 0) {// 无声音，且上一次的声音也为0，那么给一个初始值
                    setVideoVolume(2);
                } else {
                    setVideoVolume(mOldVolume);
                }
            } else {
                mOldVolume = curVolume;
                setVideoVolume(0);
            }
        }
    }

    @Override
    public void setAdPlayStateListener(AdPlayStateListener adPlayStateListener) {
        mAdPlayStateListener = adPlayStateListener;
    }

    @Override
    public void onADPlayStateChange(Bundle bundle) {
        int state = PLAY_STATE_DILE;
        if (null != bundle) {
            state = bundle.getInt(KEY_STATE);
        }
        switch (state) {
        case PLAY_STATE_STARTED: {
            if (null != mTimeTextView) {
                mTimeTextView.setText(mCountDownDur);
                startTimer();
            }
            mHandler.removeMessages(MSG_LOADING_TIMEOUT);
            break;
        }
        case PLAY_STATE_ERROR:
        case PLAY_STATE_COMPLETE: {
            closeAD();
            mHandler.removeMessages(MSG_LOADING_TIMEOUT);
            break;
        }
        default: {
            LogInfo.log(TAG, "onADPlayStateChange default state=" + state);
            break;
        }
        }
        if (null != mAdPlayStateListener) {
            mAdPlayStateListener.onADPlayStateChange(bundle);
        }
    }

    private void notifyPlayState(int state) {
        LogInfo.log(TAG, "notifyPlayState mAdType=" + mAdType + " state="
                + state);
        if (null != mAdPlayStateListener) {
            Bundle bundle = new Bundle();
            bundle.putInt(KEY_STATE, state);
            mAdPlayStateListener.onADPlayStateChange(bundle);
        }
    }

    private void startTimer() {
        stopTimer();
        mStartTime = System.currentTimeMillis();
        mHandler.sendEmptyMessageDelayed(MSG_COUNT_DOWN, FREQUENCY_COUNT_DOWN);
    }

    private void stopTimer() {
        if (mHandler.hasMessages(MSG_COUNT_DOWN)) {
            mHandler.removeMessages(MSG_COUNT_DOWN);
        }
    }

    @Override
    public boolean onLoadComplete() {
        LogInfo.log(TAG, "onLoadComplete mAdMaterialLoadListener="
                + mAdMaterialLoadListener);
        return mAdMaterialLoadListener.onLoadComplete();
    }

    @Override
    public void onLoadFailed() {
        closeAD();
        mAdMaterialLoadListener.onLoadFailed();
    }

    public void setVideoVolume(int index) {
        boolean isSilent = (index <= 0);
        if (null != mMuteView) {
            mMuteView.setImageResource(isSilent ? R.drawable.letv_boot_mute
                    : R.drawable.letv_boot_not_mute);
        }
        if (isSilent) {
            mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 0, 0);
        } else {
            mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, index, 0); // tempVolume:音量绝对值
        }
    }

    private int getVideoVolume() {
        return mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
    }
}
